package com.ktg.mes.wm.service.impl;

import java.math.BigDecimal;
import java.sql.Date;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import com.ktg.common.utils.DateUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ktg.common.utils.SecurityUtils;
import com.ktg.mes.md.domain.MdItem;
import com.ktg.mes.md.domain.MdProductBom;
import com.ktg.mes.md.service.IItemTypeService;
import com.ktg.mes.md.service.IMdProductBomService;
import com.ktg.mes.pro.domain.ProItemNeed;
import com.ktg.mes.pro.service.IProItemNeedService;
import com.ktg.mes.unit.sql.service.SQLToolService;
import com.ktg.mes.unit.sync.SyncModel;
import com.ktg.mes.unit.sync.service.IFromService;
import com.ktg.mes.unit.sync.service.IToService;
import com.ktg.mes.wm.domain.WmMaterialStock;
import com.ktg.mes.wm.domain.WmWarehouse;
import com.ktg.mes.wm.service.IWmMaterialStockService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ktg.mes.wm.mapper.WmMaterialStatisticsMapper;
import com.ktg.mes.wm.domain.WmMaterialStatistics;
import com.ktg.mes.wm.service.IWmMaterialStatisticsService;



/**
 * 库存实况Service业务层处理
 *
 * @author byteco
 * @date 2022-12-13
 */
@Service
public class WmMaterialStatisticsServiceImpl extends ServiceImpl<WmMaterialStatisticsMapper, WmMaterialStatistics> implements IWmMaterialStatisticsService
{
    @Autowired
    private IWmMaterialStockService wmMaterialStockService;

    @Autowired
    private IProItemNeedService proItemNeedService;

    @Autowired
    private IMdProductBomService mdProductBomService;


    @Autowired
    private IFromService fromService;

    @Autowired
    private SQLToolService toIService;

    /**
     * 查询库存实况
     *
     * @param entity 库存实况
     * @param page 分页对象
     * @return 库存实况
     */
    @Override
    public IPage<WmMaterialStatistics> queryPageList(WmMaterialStatistics entity, Page<WmMaterialStatistics> page) {
        QueryWrapper<WmMaterialStatistics> lqw = new QueryWrapper<WmMaterialStatistics>(entity);
        lqw.orderByDesc("create_time");
        IPage<WmMaterialStatistics> pageList = this.page(page, lqw);
        return pageList;
    }

    /**
     * 查询库存实况
     *
     * @param entity 库存实况
     * @return 库存实况
     */
    @Override
    public List<WmMaterialStatistics> queryList(WmMaterialStatistics entity) {
        QueryWrapper<WmMaterialStatistics> lqw = new QueryWrapper<WmMaterialStatistics>(entity);
        lqw.orderByDesc("create_time");
        return this.list(lqw);
    }

    public WmMaterialStatistics getInfo(Long id)
    {
        return this.getById(id);
    }


    /**
     * 新增库存实况
     *
     * @param entity 库存实况
     * @return 结果
     */
    @Override
    public void insert(WmMaterialStatistics entity)
    {
        entity.setCreateBy(SecurityUtils.getUsername());
        entity.setCreateTime(DateUtils.getNowDate());
        this.save(entity);
    }

    /**
     * 修改库存实况
     *
     * @param entity 库存实况
     * @return 结果
     */
    @Override
    public boolean update(WmMaterialStatistics entity)
    {
        entity.setUpdateBy(SecurityUtils.getUsername());
        entity.setUpdateTime(DateUtils.getNowDate());
        return this.updateById(entity);
    }

    /**
     * 批量删除库存实况
     *
     * @param recordIds 需要删除的库存实况主键
     * @return 结果
     */
    @Override
    public boolean delete(Long[] recordIds)
    {

        return this.removeByIds(Arrays.asList(recordIds));
    }

    /**
     * 删除库存实况信息
     *
     * @param recordId 库存实况主键
     * @return 结果
     */
    @Override
    public boolean delete(Long recordId)
    {
        return this.removeById(recordId);
    }

    private LambdaQueryWrapper<WmMaterialStatistics> buildQueryWrapper(WmMaterialStatistics entity) {
        LambdaQueryWrapper<WmMaterialStatistics> lqw = Wrappers.lambdaQuery();
                    lqw.eq(StringUtils.isNotBlank(entity.getItemCode()), WmMaterialStatistics::getItemCode, entity.getItemCode());
                    lqw.like(StringUtils.isNotBlank(entity.getItemName()), WmMaterialStatistics::getItemName, entity.getItemName());
                    lqw.eq(StringUtils.isNotBlank(entity.getSpecification()), WmMaterialStatistics::getSpecification, entity.getSpecification());
                    lqw.eq(StringUtils.isNotBlank(entity.getUnitOfMeasure()), WmMaterialStatistics::getUnitOfMeasure, entity.getUnitOfMeasure());
                    lqw.eq(StringUtils.isNotBlank(entity.getViscosity()), WmMaterialStatistics::getViscosity, entity.getViscosity());
                    lqw.eq(entity.getQuantityOnhand() != null, WmMaterialStatistics::getQuantityOnhand, entity.getQuantityOnhand());
                    lqw.eq(entity.getQuantityWillOut() != null, WmMaterialStatistics::getQuantityWillOut, entity.getQuantityWillOut());
                    lqw.eq(entity.getQuantityProduct() != null, WmMaterialStatistics::getQuantityProduct, entity.getQuantityProduct());
                    lqw.eq(entity.getQuantityNeed() != null, WmMaterialStatistics::getQuantityNeed, entity.getQuantityNeed());
        return lqw;
    }


    public WmMaterialStatistics findOne(MdItem mdItem){
        WmMaterialStatistics materialStock = new WmMaterialStatistics();
        materialStock.setItemId(mdItem.getItemId());
        QueryWrapper<WmMaterialStatistics> wmMaterialStockQueryWrapper = new QueryWrapper<>(materialStock);
        materialStock = getOne(wmMaterialStockQueryWrapper);
        if (materialStock == null) {
            materialStock = new WmMaterialStatistics();
            materialStock.setItemTypeId(mdItem.getItemTypeId());
            materialStock.setItemId(mdItem.getItemId());
            materialStock.setItemCode(mdItem.getItemCode());
            materialStock.setItemName(mdItem.getItemName());
            materialStock.setSpecification(mdItem.getSpecification());
            materialStock.setUnitOfMeasure(mdItem.getUnitOfMeasure());
            materialStock.setViscosity(mdItem.getViscosity());
        }
        return materialStock;
    }


    /**
     * 创建和更新 库存数量
     * @param mdItem
     */
    public  void updateOrCreateStockFromStatistics(MdItem mdItem){
        MdProductBom productBom = new MdProductBom();
        productBom.setItemId(mdItem.getItemId());
        QueryWrapper<MdProductBom> mdProductBomQueryWrapper = new QueryWrapper<>(productBom);


        WmMaterialStatistics materialStatistics = findOne(mdItem);
        String selectCount = "SUM(quantity_onhand)";
        WmMaterialStock wmMaterialStock = new WmMaterialStock();
        wmMaterialStock.setItemId(mdItem.getItemId());
        QueryWrapper<WmMaterialStock> materialStockQueryWrapper = new QueryWrapper<>(wmMaterialStock);
        materialStockQueryWrapper.select(selectCount);
        Map map = wmMaterialStockService.getMap(materialStockQueryWrapper);
        int count = 0;
        if (map != null && map.get(selectCount) != null){
            count = Integer.valueOf(map.get(selectCount).toString());
        }
        materialStatistics.setQuantityOnhand(BigDecimal.valueOf(count));

        if (materialStatistics.getRecordId() == null){
            save(materialStatistics);

        }else {
            updateById(materialStatistics);
        }
    }



    /**
     * 创建和更新 预出库数量
     * @param mdItem
     */
    public  void updateOrCreateWillOutFromStatistics(MdItem mdItem){
        WmMaterialStatistics materialStatistics = findOne(mdItem);

        String selectCount = "SUM(quantity_onhand)";

        ProItemNeed itemNeed = new ProItemNeed();
        itemNeed.setItemId(String.valueOf(mdItem.getItemId()));
        QueryWrapper<ProItemNeed> materialStockQueryWrapper = new QueryWrapper<>(itemNeed);
        materialStockQueryWrapper.select(selectCount);
        //未发货
        materialStockQueryWrapper.eq("shipped_type",Integer.valueOf(1));
        Map map = proItemNeedService.getMap(materialStockQueryWrapper);

        int count = 0;
        if (map != null && map.get(selectCount) != null){
            count = Integer.valueOf(map.get(selectCount).toString());
        }
        materialStatistics.setQuantityWillOut(BigDecimal.valueOf(count));

        if (materialStatistics.getRecordId() == null){
            save(materialStatistics);
        }else {
            updateById(materialStatistics);
        }
    }


    /**
     * 创建和更新 需求数量
     * @param mdItem
     */
    public  void updateOrCreateNeedFromStatistics(MdItem mdItem){
        WmMaterialStatistics materialStatistics = findOne(mdItem);

        String selectCount = "SUM(quantity_onhand)";

        ProItemNeed itemNeed = new ProItemNeed();
        itemNeed.setItemId(String.valueOf(mdItem.getItemId()));
        QueryWrapper<ProItemNeed> materialStockQueryWrapper = new QueryWrapper<>(itemNeed);
        materialStockQueryWrapper.select(selectCount);
        //未发货
        materialStockQueryWrapper.eq("shipped_type",Integer.valueOf(0));

        Map map = proItemNeedService.getMap(materialStockQueryWrapper);

        int count = 0;
        if (map != null && map.get(selectCount) != null){
            count = Integer.valueOf(map.get(selectCount).toString());
        }
        materialStatistics.setQuantityNeed(BigDecimal.valueOf(count));

        if (materialStatistics.getRecordId() == null){
            save(materialStatistics);
        }else {
            updateById(materialStatistics);
        }
    }


    /**
     * 同步库存
     */
    public void sysnStock(){
        SyncModel syncModel = new SyncModel();
        syncModel.setService(fromService,toIService);
        String tableName = "(SELECT\n" +
                "\tMAX(AutoID) as AutoID,cInvCode,cBatch,cWhCode,cWhName,cBarCode,cInvName,cInvStd,cInvDefine1,cInvDefine2,cInvDefine3,SUM (quantity) AS iQuantity\n" +
                "FROM\n" +
                "\t(\n" +
                "\tSELECT\n" +
                "\t\tAutoID,\n" +
                "\t\tCurrentStock.cBatch,\n" +
                "\t\tCurrentStock.cWhCode,\n" +
                "\t\tcWhName,\n" +
                "\t\tWarehouse.cBarCode,\n" +
                "\t\tCurrentStock.cInvCode,\n" +
                "\t\tcInvName,\n" +
                "\t\tcInvStd,\n" +
                "\t\tcInvDefine1,\n" +
                "\t\tcInvDefine2,\n" +
                "\t\tcInvDefine3,\n" +
                "\t\t(iQuantity + fOutQuantity + fInQuantity) AS quantity \n" +
                "\tFROM\n" +
                "\t\tCurrentStock\n" +
                "\t\tLEFT JOIN Inventory ON CurrentStock.cInvCode = Inventory.cInvCode\n" +
                "\t\tLEFT JOIN Warehouse ON CurrentStock.cWhCode = Warehouse.cWhCode\n" +
                "\t) P GROUP BY AutoID,cInvCode,cBatch,cWhCode,cWhName,cBarCode,cInvName,cInvStd,cInvDefine1,cInvDefine2,cInvDefine3)P";

        syncModel.setTable(tableName,"wm_material_stock");
        syncModel.setSyncData("AutoID",null,"material_stock_id",null);

        syncModel.addColumn("AutoID","material_stock_id", SyncModel.SyncModelType.TypeString);
        syncModel.addColumn("cBatch","batch_code", SyncModel.SyncModelType.TypeString);

        syncModel.addColumn("cWhCode","warehouse_id", SyncModel.SyncModelType.TypeString);
        syncModel.addColumn("cBarCode","warehouse_code", SyncModel.SyncModelType.TypeString);
        syncModel.addColumn("cWhName","warehouse_name", SyncModel.SyncModelType.TypeString);

        syncModel.addColumn("cInvCode","item_code", SyncModel.SyncModelType.TypeString);
        syncModel.addColumn("cInvName","item_name", SyncModel.SyncModelType.TypeString);
        syncModel.addColumn("cInvStd","specification", SyncModel.SyncModelType.TypeString);
        syncModel.addColumn("cInvDefine1","viscosity", SyncModel.SyncModelType.TypeString);
        syncModel.addColumn("cInvDefine2","tag", SyncModel.SyncModelType.TypeString);
        syncModel.addColumn("cInvDefine3","packing_type", SyncModel.SyncModelType.TypeString);

        syncModel.addColumn("iQuantity","quantity_onhand", SyncModel.SyncModelType.TypeString);

        syncModel.synsStart("库存量信息");

//        getBaseMapper().updateProductItemId();
//        getBaseMapper().updateWareHouseId();

    }




}
